package com.ll.daipao.controller;

import com.github.binarywang.wxpay.bean.request.WxEntPayRequest;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.bean.result.WxEntPayResult;
import com.github.binarywang.wxpay.bean.result.WxPayUnifiedOrderResult;
import com.github.binarywang.wxpay.config.WxPayConfig;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.binarywang.wxpay.util.SignUtils;
import com.google.gson.Gson;
import com.ll.daipao.handler.Constants;
import com.ll.daipao.service.OrderService;
import com.ll.daipao.util.ReturnModel;
import com.ll.daipao.util.Sha1Util;
import com.ll.daipao.util.XMLUtil;
import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken;
import me.chanjar.weixin.mp.bean.result.WxMpUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import sun.applet.Main;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Map;

/**
 * Created by rockyll on 2017/11/30.
 */
@Controller
public class PaymentController extends GenericController{
    @Autowired
    private WxPayConfig payConfig;
    @Autowired
    private WxPayService payService;
    @Resource(name = "wxMpService2")
    protected WxMpService wxMpService2;
    @Autowired
    private OrderService orderService;


    /**
     * 用于返回预支付的结果 WxMpPrepayIdResult，一般不需要使用此接口
     *
     * @param response
     * @param request
     * @throws WxErrorException
     */
    @RequestMapping(value = "getPrepayIdResult")
    public void getPrepayId(HttpServletResponse response,
                            HttpServletRequest request) throws WxErrorException, WxPayException {
        WxPayUnifiedOrderRequest payInfo = WxPayUnifiedOrderRequest.newBuilder()
                .openid(request.getParameter("openid"))
                .outTradeNo(request.getParameter("out_trade_no"))
                .totalFee(Integer.valueOf(request.getParameter("total_fee")))
                .body(request.getParameter("body"))
                .tradeType(request.getParameter("trade_type"))
                .spbillCreateIp(request.getParameter("spbill_create_ip"))
                .notifyURL("")
                .build();
        this.logger
                .info("PartnerKey is :" + this.payConfig.getMchKey());
        WxPayUnifiedOrderResult result = this.payService.unifiedOrder(payInfo);
        this.logger.info(new Gson().toJson(result));
        renderString(response, result);
    }

    /**
     * 返回前台H5调用JS支付所需要的参数，公众号支付调用此接口
     *
     * @param response
     * @param request
     */
    @RequestMapping(value = "getJSSDKPayInfo" ,produces="application/json;charset=UTF-8",method = RequestMethod.POST)
    public void getJSSDKPayInfo(HttpServletResponse response,
                                HttpServletRequest request) {
        String id = request.getParameter("id");
        String openid = (String) request.getSession().getAttribute(Constants.WX_PAY_OPENID);
        String amount = request.getParameter("amount");
        ReturnModel returnModel = new ReturnModel();
        WxPayUnifiedOrderRequest prepayInfo = WxPayUnifiedOrderRequest.newBuilder()
                .openid(openid)
                .outTradeNo(id)
                .totalFee(Integer.parseInt(amount))
                .body("我是测试")
                .tradeType("JSAPI")
                .spbillCreateIp("127.0.0.1")
                .notifyURL(Constants.REAL_URL+"daipao/getJSSDKCallbackData?id="+id)//TODO(user) 填写通知回调地址
                .build();

        try {
            Map<String, String> payInfo = this.payService.getPayInfo(prepayInfo);
            returnModel.setResult(true);
            returnModel.setDatum(payInfo);
            renderString(response, returnModel);
        } catch (WxPayException e) {
            returnModel.setResult(false);
            returnModel.setReason(e.getErrCodeDes());
            renderString(response, returnModel);
            this.logger.error(e.getErrCodeDes());
        }
    }

    /**
     * 微信通知支付结果的回调地址，notify_url
     *
     * @param request
     * @param response
     */
    @RequestMapping(value = "getJSSDKCallbackData")
    public void getJSSDKCallbackData(HttpServletRequest request,
                                     HttpServletResponse response) {
        try {
            synchronized (this) {
                Map<String, String> kvm = XMLUtil.parseRequestXmlToMap(request);
                if (kvm.get("result_code").equals("SUCCESS")) {
                    //TODO(user) 微信服务器通知此回调接口支付成功后，通知给业务系统做处理
                    logger.info("out_trade_no: " + kvm.get("out_trade_no") + " pay SUCCESS!");
                    String id = kvm.get("out_trade_no");
                    orderService.paySuccessUpdateOrder(id);
                    logger.info("我成功了");
                    response.getWriter().write("<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[ok]]></return_msg></xml>");
                } else {
                    this.logger.error("out_trade_no: "
                            + kvm.get("out_trade_no") + " result_code is FAIL");
                    response.getWriter().write(
                            "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[result_code is FAIL]]></return_msg></xml>");
                }
//                if (SignUtils.checkSign(kvm, null, this.payConfig.getMchKey())) {
//
//                } else {
//                    response.getWriter().write(
//                            "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[check signature FAIL]]></return_msg></xml>");
//                    this.logger.error("out_trade_no: " + kvm.get("out_trade_no")
//                            + " check signature FAIL");
//                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @RequestMapping(value = "entPay")
    public void payToIndividual(HttpServletResponse response,
                                HttpServletRequest request) {
        WxEntPayRequest wxEntPayRequest = new WxEntPayRequest();
        wxEntPayRequest.setAppid(payConfig.getAppId());
        wxEntPayRequest.setMchId(payConfig.getMchId());
        wxEntPayRequest.setNonceStr(Sha1Util.getNonceStr());
        wxEntPayRequest.setPartnerTradeNo(request.getParameter("partner_trade_no"));
        wxEntPayRequest.setOpenid(request.getParameter("openid"));
        wxEntPayRequest.setCheckName("NO_CHECK");
        wxEntPayRequest.setAmount(Integer.valueOf(request.getParameter("amount")));
        wxEntPayRequest.setDescription(request.getParameter("desc"));
        wxEntPayRequest.setSpbillCreateIp(request.getParameter("spbill_create_ip"));

        try {
            WxEntPayResult wxEntPayResult = payService.entPay(wxEntPayRequest);
            if ("SUCCESS".equals(wxEntPayResult.getResultCode().toUpperCase())
                    && "SUCCESS".equals(wxEntPayResult.getReturnCode().toUpperCase())) {
                this.logger.info("企业对个人付款成功！\n付款信息：\n" + wxEntPayResult.toString());
            } else {
                this.logger.error("err_code: " + wxEntPayResult.getErrCode()
                        + "  err_code_des: " + wxEntPayResult.getErrCodeDes());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     * 跨行支付
     * @param request
     * @param response
     * @return
     */
    @RequestMapping("sigin2")
    public String sigin2(HttpServletRequest request, HttpServletResponse response){
        StringBuffer sb = new StringBuffer();
        sb.append("https://open.weixin.qq.com/connect/oauth2/authorize?")
                .append("appid="+wxMpService2.getWxMpConfigStorage().getAppId())
                .append("&redirect_uri="+Constants.REAL_URL+"daipao/gotoPay")
                .append("&response_type=code")
                //静默授权snsapi_base
                .append("&scope=snsapi_base")
                .append("&state=state")
                .append("#wechat_redirect");

        try {
            response.sendRedirect(sb.toString());
        } catch (IOException e) {
            this.logger.error(e.getMessage(),e);
        }
        return null;
    }


    /**
     * 通过code获得基本用户信息
     * 详情请见: http://mp.weixin.qq.com/wiki/14/bb5031008f1494a59c6f71fa0f319c66.html
     *
     * @param response
     */
    @RequestMapping(value = "gotoPay")
    public String gotoPay(HttpServletRequest request , HttpServletResponse response) {
        String code = request.getParameter("code");
        String lang = request.getParameter("lang");
        WxMpOAuth2AccessToken accessToken;
        WxMpUser wxMpUser;
        try {
            accessToken = wxMpService2.oauth2getAccessToken(code);
            request.getSession().setAttribute(Constants.WX_PAY_OPENID,accessToken.getOpenId());
            response.sendRedirect(Constants.REAL_URL+"daipao/send/taskObtain");
        } catch (WxErrorException e) {
            this.logger.error(e.getError().toString());
        } catch (IOException e) {
            this.logger.error(e.getMessage(),e);
        }
        return null;
    }




}
